package com.xique.park.service.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xique.common.core.utils.DateUtils;
import com.xique.common.core.utils.StringUtils;
import com.xique.park.bean.domain.ParkOut;
import com.xique.park.bean.domain.ParkOutV1;
import com.xique.park.bean.dto.ParkInOutDelDto;
import com.xique.park.bean.dto.ParkOutDto;
import com.xique.park.controller.client.web.bean.search.ParkOutSearch;
import com.xique.park.mapper.ParkOutMapper;
import com.xique.park.mapper.ParkOutMapperV1;
import com.xique.park.service.service.IParkOutService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * 出场记录Service业务层处理
 *
 * @author xique
 * @date 2021-12-09
 */
@Slf4j
@Service
public class ParkOutServiceImpl extends ServiceImpl<ParkOutMapper, ParkOut> implements IParkOutService {

    @Autowired
    private ParkOutMapper parkOutMapper;

    @Autowired
    private ParkOutMapperV1 parkOutMapperV1;

    @Autowired
    private SqlSessionFactory sqlSessionFactory;

    /**
     * 查询出场记录
     *
     * @param id 出场记录ID
     * @return 出场记录
     */
    @Override
    public ParkOut selectParkOutById(Long id) {
        return parkOutMapper.selectParkOutById(id);
    }

    @Override
    public List<ParkOut> selectParkOutByIds(List<Long> parkOutIdList) {
        return parkOutMapper.selectParkOutByIds(parkOutIdList);
    }

    /**
     * 查询出场记录列表
     *
     * @param parkOut 出场记录
     * @return 出场记录
     */
    @Override
    public List<ParkOut> selectParkOutList(ParkOut parkOut) {
        return parkOutMapper.selectParkOutList(parkOut);
    }

    /**
     * 新增出场记录
     *
     * @param parkOut 出场记录
     * @return 结果
     */
    @Override
    public int insertParkOut(ParkOut parkOut) {
        parkOut.setCreateTime(DateUtils.getNowDate());
        return parkOutMapper.insertParkOut(parkOut);
    }

    /**
     * 修改出场记录
     *
     * @param parkOut 出场记录
     * @return 结果
     */
    @Override
    public int updateParkOut(ParkOut parkOut) {
        parkOut.setUpdateTime(DateUtils.getNowDate());
        return parkOutMapper.updateParkOut(parkOut);
    }

    /**
     * 批量删除出场记录
     *
     * @param ids 需要删除的出场记录ID
     * @return 结果
     */
    @Override
    public int deleteParkOutByIds(Long[] ids) {
        return parkOutMapper.deleteParkOutByIds(ids);
    }

    @Override
    public int batchInsert(List<ParkOut> list) {
        return parkOutMapper.insertBatch(list);
    }

    @Override
    public int batchUpdate(List<ParkOut> list) {
        return parkOutMapper.updateBatch(list);
    }

    @Override
    public Integer selectParkInfoNumByToday(
            Integer province, Integer city, Integer district, Long deptId, Long parkInfoId) {
        return parkOutMapper.selectParkInfoNumByToday(province, city, district, deptId, parkInfoId);
    }

    @Override
    public List<ParkOutDto> selectParkOutByParkingSerial(Long parkId, String parkingSerial) {
        return parkOutMapper.selectParkOutByParkingSerial(parkId, parkingSerial);
    }

    @Override
    public ParkOutV1 selectParkOut(ParkOutSearch search) {
        QueryWrapper<ParkOutV1> wrapper = new QueryWrapper<>();
        if (null != search.getLaneIds()) {
            wrapper.in("out_lane_id", search.getLaneIds());
        }
        if (StringUtils.isNotEmpty(search.getParkingSerial())) {
            wrapper.eq("parking_serial", search.getParkingSerial());
        }
        if (null != search.getParkId()) {
            wrapper.eq("park_id", search.getParkId());
        }
        if (StringUtils.isNotEmpty(search.getOutCarPlate())) {
            wrapper.eq("out_car_plate", search.getOutCarPlate());
        }
        wrapper.orderByDesc("UNIX_TIMESTAMP(update_time)").last("limit 1");

        return parkOutMapperV1.selectOne(wrapper);
    }

    @Override
    public List<ParkOut> selectLastParkOutListByLaneId(Long parkId, List<Long> laneIds) {
        if (CollectionUtils.isEmpty(laneIds)) {
            return new ArrayList<>();
        }
        return parkOutMapper.selectLastParkOutListByLaneId(parkId, laneIds);
    }

    /**
     * 统计车场某段时间内的车辆出场数量
     */
    @Override
    public long getOutCarRevenue(Long parkId, Date starDate, Date endDate) {
        return parkOutMapper.getOutCarRevenue(parkId, starDate, endDate);
    }

    @Override
    public List<ParkOut> getParkOutList(ParkOut parkOut) {
        return parkOutMapper.getParkOutList(parkOut);
    }

    @Override
    public List<ParkOutDto> statisticsByMngTypeAndDay(Long parkId, List<String> mngTypeList) {
        return parkOutMapper.statisticsByMngTypeAndDay(parkId, mngTypeList);
    }

    @Override
    public long statisticsByMngTypeAndAppointDay(Long parkId, String day, List<String> mngTypeList) {
        return parkOutMapper.statisticsByMngTypeAndAppointDay(parkId, day, mngTypeList);
    }

    @Override
    public List<ParkOut> selectParkOut(ParkOut parkOut) {
        return parkOutMapper.selectParkOut(parkOut);
    }

    @Override
    public List<ParkOut> selectParkOutIdByOutLaneId(Long parkId, List<Long> laneIdList, int limit) {
        return parkOutMapper.selectParkOutIdByOutLaneId(parkId, laneIdList, limit);
    }

    @Override
    public List<String> selectDeleteDate(Long parkId, String beforeDate) {
        return parkOutMapper.selectDeleteDate(parkId, beforeDate);
    }

    @Override
    public Long selectDeleteCount(Long parkId, String delData) {
        return parkOutMapper.selectDeleteCount(parkId, delData);
    }

    @Override
    public List<ParkInOutDelDto> selectParkInAndOutList(Long parkId, String delData) {
        return parkOutMapper.selectParkInAndOutList(parkId, delData);
    }

    @Override
    public void batchDel(Set<Long> outIdSet) {
        long startTime = System.currentTimeMillis();
        SqlSession sqlSession = null;
        try {
            sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
            ParkOutMapper parkOutMapper = sqlSession.getMapper(ParkOutMapper.class);
            outIdSet.forEach(parkOutMapper::deleteParkOutById);
            sqlSession.commit();
            sqlSession.clearCache();
        } catch (Exception e) {
            log.info("[出场记录服务]-批量删除异常，异常信息：{}", e.getMessage());
            e.printStackTrace();
            if (sqlSession != null) {
                sqlSession.rollback();
            }
        } finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
        log.info("[出场记录服务]-批量删除耗时：{}毫秒", System.currentTimeMillis() - startTime);
    }

    @Override
    public List<ParkOut> selectParkOutByParkIdAndOutTime(Long parkId, String outTime) {
        return parkOutMapper.selectParkOutByParkIdAndOutTime(parkId, outTime);
    }

}
